package com.ly.mp.busicen.rule;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import com.alibaba.fastjson.JSONObject;
import com.ly.mp.busicen.rule.field.article.FieldArticleContainer;
import com.ly.mp.busicen.rule.field.article.IFieldArticle;
import com.ly.mp.busicen.rule.flow.FlowSpelMethods;
import com.ly.mp.busicen.rule.flow.FlowUserMode;
import com.ly.mp.busicen.rule.flow.IActionContainer;
import com.ly.mp.busicen.rule.flow.action.Action;
import com.ly.mp.busicen.rule.flow.action.IAction;
import com.ly.mp.busicen.rule.flow.action.OperationType;

public class RuleReLoad implements IRuleReload, ApplicationContextAware {

	ApplicationContext application;

	@Autowired
	IActionContainer actionContainer;

	@Autowired
	FieldArticleContainer fieldArticleContainer;

	@Override
	public boolean reload() {
		Map<String, IRuleReload> ruleLoads = application.getBeansOfType(IRuleReload.class);
		Collection<IRuleReload> list = ruleLoads.values();
		for (IRuleReload iRuleReload : list) {
			if (iRuleReload != this) {
				iRuleReload.reload();
			}
		}
		return false;
	}

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		application = applicationContext;
	}

	public String ruleData(String flow, String app) {
		List<IAction> action = actionContainer.flowActions(flow, FlowUserMode.currentContext(null));
		action.stream().map(m -> {
			Action act = (Action) m;
			Map<String, Object> map = FlowSpelMethods.mapnew();
			if (act.getOperation() == OperationType.DATACHECK || act.getOperation() == OperationType.FIELDCHECK
					|| act.getOperation() == OperationType.SCRIPT) {
				map.put("EXIT", act.getOperation());
			}
			XruleStrUtils.splitToList(act.nextAction(), ";").stream().forEach(f -> {
				map.put(XruleStrUtils.splitZKH(f), XruleStrUtils.splitJKH(f));
			});
			act.extention().put("nas", map);
			if (act.getOperation() == OperationType.FIELDCHECK) {
				String articleType = XruleStrUtils.splitXKH(act.content()).replace(",", "");
				List<IFieldArticle> articles = fieldArticleContainer.getArticles(articleType,FlowUserMode.currentContext(null));
				act.extention().put("fields", FlowSpelMethods.map(articles));
			}
			return act;
		}).collect(Collectors.toList());
		String result = JSONObject.toJSONString(action);
		return result;
	}

	private static Logger log = LoggerFactory.getLogger(RuleReLoad.class);
	
	@SuppressWarnings("unchecked")
	public static <T> T cloneObj(T obj) {
		T retVal = null;
		try (ByteArrayOutputStream baos = new ByteArrayOutputStream();
				ObjectOutputStream oos = new ObjectOutputStream(baos);) {
			oos.writeObject(obj);

			try (ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
					ObjectInputStream ois = new ObjectInputStream(bais);) {
				retVal = (T) ois.readObject();
			} catch (Exception e) {
				throw e;
			}
		} catch (Exception e) {
			log.error("深拷贝异常",e);
			throw new RuntimeException(e);
		}
		return retVal;
	}

}
